<?php

namespace C\S\Activity;

use C\L\Service;
use Phalcon\Mvc\Model\Query;

class Share extends Service
{
    protected function setModel()
    {
        $this->model = new \C\M\Share();
    }

    public function getStatusConfig()
    {
        return [
        'status' => [
        'Y' => '成功',
        'N' => '失效',
        'D' => '已忽略',
        'S' => '已申请',
        'C' => '已取消'
        ],
        'front_status' => [
        'Y' => '成功',
        'N' => '失效',
        'D' => '已忽略',
        'S' => '已申请',
        'C' => '已取消'
        ],
        ];
    }

  /**
   * Review share record
   * @param $id int
   * @param $status string
   **/
    public function review($id, $status)
    {
        $share = $this->findShareRecordById($id);
        if (!$share) {
            throw new \Exception('分享记录不存在');
        }

        $createdDate = $share['addtime'];
        $startDate   = mktime(0, 0, 0, date("m", $createdDate), date("d", $createdDate), date("Y", $createdDate));
        $endDate     = mktime(0, 0, 0, date("m", $createdDate), date("d", $createdDate) + 1, date("Y", $createdDate));

        $userId = $share['uid'];

        try {
            $this->di['db']->begin();

          // 判断当日是否有成功记录
            $hasSuccessRecord = $this->findSuccessRecord($userId, $startDate, $endDate);
            if ($hasSuccessRecord) {
              // 将当日所有未处理记录状态置为失败
                $this->failUnprocessRecords($userId, $startDate, $endDate);
                $this->di['db']->commit();
                throw new \Exception('当日已有成功记录');
            }

          //  更新记录目标状态
            $updateResult = $this->updateRecord($id, $status);
            if (!$updateResult) {
                throw new \Exception('更新分享记录失败');
            }

            if ($status == 'Y') {
              // 发放奖励
                $fundAddResult = $this->dispatchShareReward($share);
                if (!$fundAddResult) {
                    throw new \Exception('流水添加失败');
                }

              // 将当日所有未处理记录状态置为失败
                $this->failUnprocessRecords($userId, $startDate, $endDate);
            }

            $this->di['db']->commit();

            return true;
        } catch (\Exception $error) {
            $isUnderTransaction = $this->di['db']->isUnderTransaction();

            if ($isUnderTransaction) {
                $this->di['db']->rollback();
            }

            throw $error;

            return false;
        }
    }

    public function findSuccessRecord($userId, $startDate, $endDate)
    {
        $phql = 'SELECT * FROM C\M\Share ' .
        'WHERE uid = :user_id:' .
        'AND status = :status: ' .
        'AND addtime >= :start_date: ' .
        'AND addtime < :end_date:';

        $query = new Query($phql, $this->getDi());

        $result = $query->getSingleResult([
        'user_id'    => $userId,
        'status'     => 'Y',
        'start_date' => $startDate,
        'end_date'   => $endDate,
        ]);

        return (bool) $result;
    }

    private function findShareRecordById($id)
    {
        $phql = '' .
        'SELECT * FROM C\M\Share ' .
        'WHERE id = :id: ' .
        'LIMIT 1';

        $query = new Query($phql, $this->getDi());

        $result = $query->getSingleResult(compact('id'));

        return $result ? $result->toArray() : $result;
    }

    private function updateRecord($id, $status)
    {
        $phql = 'UPDATE C\M\Share ' .
        'SET status = :status: ' .
        'WHERE id = :id:';

        $query = new Query($phql, $this->getDi());

        $result = $query->execute(compact('id', 'status'));

        return $result->success();
    }

    private function failUnprocessRecords($userId, $startDate, $endDate)
    {
        $phql = 'UPDATE C\M\Share ' .
        'SET status = :next_status: ' .
        'WHERE uid = :user_id:' .
        'AND status = :status:' .
        'AND addtime >= :start_date: ' .
        'AND addtime < :end_date:';

        $query = new Query($phql, $this->getDi());

        $result = $query->execute([
        'user_id'     => $userId,
        'status'      => 'S',
        'next_status' => 'N',
        'start_date'  => $startDate,
        'end_date'    => $endDate,
        ]);

        return $result->success();
    }

    private function dispatchShareReward($shareRecord)
    {
        $shareConfig = $this->di['s_config']->get('activity_share');

        return $this->di['s_funds']->add(
            $shareRecord['uid'],
            $shareConfig['amount'] ?? 0,
            'money',
            'image_share',
            '分享奖励',
            $shareRecord['id']
        );
    }
}
